from typing import Any, Awaitable, Callable, Dict

from aiogram import BaseMiddleware
from aiogram.types import TelegramObject
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker

import src.infrastructure.db.repositories as repo
from src.application.category.service import CategoryService
from src.application.order.service import OrderService
from src.application.proxy.service import ProxyService
from src.application.user.service import UserService
from src.infrastructure.db.repositories import CategoryReaderImpl
from src.infrastructure.db.uow import SQLAlchemyUoW
from src.infrastructure.db.uow.uow import build_uow


class UowMiddleware(BaseMiddleware):
    def __init__(self, sessionmaker: async_sessionmaker[AsyncSession]) -> None:
        self._pool = sessionmaker

    async def __call__(
        self,
        handler: Callable[[TelegramObject, Dict[str, Any]], Awaitable[Any]],
        event: TelegramObject,
        data: Dict[str, Any],
    ) -> Any:
        async with self._pool() as session:
            uow = build_uow(session)
            data["uow"] = uow
            data["user_service"] = UserService(uow=uow)
            data["order_service"] = OrderService(uow=uow)
            data["proxy_service"] = ProxyService(uow=uow)
            data["category_service"] = CategoryService(uow=uow)
            return await handler(event, data)
